package top.easyblog.core.support.filter;


import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import top.easyblog.common.constant.TransformStatus;
import top.easyblog.core.dao.auto.model.UrlMapping;
import top.easyblog.core.mq.RedisMessageProducer;
import top.easyblog.core.service.MappingVisitRecordService;
import top.easyblog.core.support.cache.MappingCacheManager;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URI;
import java.util.Objects;

import static org.springframework.web.cors.CorsConfiguration.ALL;

/**
 * 短链转换过滤器
 */
@Slf4j
@Component
@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class MappingTransformFilter implements TransformFilter {

    @Autowired
    private MappingCacheManager mappingCacheManager;

    @Autowired
    private MappingVisitRecordService mappingVisitRecordService;

    @Value("${custom.transform.error-page-url:https://gitee.com/LoveIT44er/projects}")
    private String errorPageUrl;

    @Override
    public void init(TransformContext context) {

    }

    @Override
    public void doFilter(TransformFilterChain chain, TransformContext context) {
        String compressionCode = context.getCompressionCode();
        UrlMapping mapping = mappingCacheManager.getCacheByCompressCode(compressionCode);
        context.setTransformStatus(TransformStatus.TRANSFORM_FAIL);
        if (Objects.nonNull(mapping)) {
            context.setTransformStatus(TransformStatus.TRANSFORM_SUCCESS);
            context.setParam(TransformContext.PARAM_LONG_URL_KEY, mapping.getSourceUrl());
            context.setParam(TransformContext.PARAM_SHORT_URL_KEY, mapping.getTinyUrl());
            chain.doFilter(context);
        } else {
            log.warn("压缩码[{}]不存在或异常,终止TransformFilterChain执行,并且重定向到404页面......", compressionCode);
            try {
                mappingVisitRecordService.sendMappingVisitMessage(context);
                Runnable redirectAction = redirect2ErrorPage(
                        context.getParam(TransformContext.PARAM_HTTP_SERVLET_RESPONSE), errorPageUrl);

                context.setRedirectAction(redirectAction);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public Runnable redirect2ErrorPage(HttpServletResponse response, String url) throws IOException {
        return () -> {
            response.setStatus(HttpStatus.NOT_FOUND.value());
            try {
                response.sendRedirect(URI.create(url).toString());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, ALL);
            response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, ALL);
            response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, Boolean.TRUE.toString());
        };
    }

    @Override
    public int order() {
        return 2;
    }

}
